<template>
	<uni-popup ref="popup" type="bottom" background-color="#fff">
		<view class="picker-container" :style="{ height: heightPx }">
			<!-- 头部搜索和确定 -->
			<view class="picker-header">
				<uni-easyinput
					v-model="searchText"
					placeholder="搜索省市区"
					class="search-input custom-easyinput"
					clearable
					:inputBorder="false"
					@input="handleSearch"
				/>
				<text class="confirm-btn" :style="{ color: themeColor }" @click="confirmPicker">
					确定
				</text>
			</view>
			<!-- 选择器主体 -->
			<view class="picker-body">
				<picker-view
					class="picker-view"
					:value="safePickerValue"
					@change="handlePickerChange"
				>
					<!-- 省份列 -->
					<picker-view-column>
						<view
							class="picker-item"
							v-for="province in filteredProvinces"
							:key="province.code"
						>
							{{ province.name }}
						</view>
					</picker-view-column>
					<!-- 城市列 -->
					<picker-view-column>
						<view class="picker-item" v-for="city in currentCities" :key="city.code">
							{{ city.name }}
						</view>
					</picker-view-column>
					<!-- 区县列 -->
					<picker-view-column>
						<view class="picker-item" v-for="area in currentAreas" :key="area.code">
							{{ area.name }}
						</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>
	</uni-popup>
</template>

<script setup>
import { ref, computed, watch } from "vue"

// =========================================================================
// RegionPicker 省市区选择组件
// 用法示例：
// <RegionPicker
//   ref="regionPicker"
//   v-model="selectedRegion"           // 绑定选中code数组，如 ['440000','440100','440106']
//   :region="regionData"                // 省市区树形数据
//   :height="400"                       // 弹窗高度，单位px，默认400
//   themeColor="#ff6600"                // 主题色，默认#007aff
//   labelKey="name"                     // 名称字段，默认name，可自定义如label
//   codeKey="code"                      // code字段，默认code，可自定义如value
//   @confirm="onRegionConfirm"           // 选中回调，返回{province, city, area}对象
// />
//
// 打开弹窗
// const regionPicker = ref(null)
// const openPicker = () => {
//   regionPicker.value?.open()
// }
// 选中回调
// const onRegionConfirm = ({ province, city, area }) => {
//   // 这里你可以做更多处理
//   console.log('选中对象', province, city, area)
// }
//
// 说明：
// - 依赖组件：uni-popup，uni-easyinput
// - v-model 绑定和回传均为[省code, 市code, 区code]数组
// - region数据字段名可通过labelKey/codeKey自定义
// - confirm事件返回完整对象（含所有字段）
// =========================================================================

const props = defineProps({
	region: {
		type: Array,
		required: true
	},
	modelValue: {
		type: Array,
		default: () => []
	},
	height: {
		type: [Number, String],
		default: 400
	},
	themeColor: {
		type: String,
		default: "#007aff"
	},
	labelKey: {
		type: String,
		default: "name"
	},
	codeKey: {
		type: String,
		default: "code"
	}
})

const emit = defineEmits(["update:modelValue", "confirm"])

const popup = ref(null)
const searchText = ref("")
const pickerValue = ref([0, 0, 0])
const regionData = ref([])

// 弹窗高度样式
const heightPx = computed(() =>
	typeof props.height === "number" ? props.height + "px" : props.height
)

// 优化的递归过滤函数
function filterRegionTree(tree, keyword) {
	if (!keyword) return tree

	const result = []
	for (const node of tree) {
		const nameMatch = node[props.labelKey]?.includes(keyword)
		const codeMatch = node[props.codeKey]?.includes(keyword)

		if (nameMatch || codeMatch) {
			result.push({ ...node })
			continue
		}

		if (node.children?.length) {
			const filteredChildren = filterRegionTree(node.children, keyword)
			if (filteredChildren.length > 0) {
				result.push({ ...node, children: filteredChildren })
			}
		}
	}
	return result
}

const filteredProvinces = computed(() => {
	return filterRegionTree(regionData.value, searchText.value.trim())
})
const currentCities = computed(() => {
	const province = filteredProvinces.value[pickerValue.value[0]]
	return province?.children || []
})

const currentAreas = computed(() => {
	const province = filteredProvinces.value[pickerValue.value[0]]
	const city = province?.children?.[pickerValue.value[1]]
	return city?.children || []
})

// 保证picker-view的value始终为合法数组
const safePickerValue = computed(() => {
	const [p, c, a] = pickerValue.value
	const provinces = filteredProvinces.value
	const cities = currentCities.value
	const areas = currentAreas.value

	return [
		Math.max(0, Math.min(p || 0, provinces.length - 1)),
		Math.max(0, Math.min(c || 0, cities.length - 1)),
		Math.max(0, Math.min(a || 0, areas.length - 1))
	]
})

// 移除这个导致循环依赖的 watch 监听器
// 改为在 safePickerValue 中处理边界情况

// 处理选择器变化
const handlePickerChange = (e) => {
	pickerValue.value = e.detail.value
}

// 处理搜索
const handleSearch = () => {
	pickerValue.value = [0, 0, 0]
}

// 打开选择器（暴露方法）
const open = () => {
	popup.value && popup.value.open("bottom")
}

// 确认选择
const confirmPicker = () => {
	const province = filteredProvinces.value[pickerValue.value[0]]
	const city = province?.children?.[pickerValue.value[1]]
	const area = city?.children?.[pickerValue.value[2]]
	// v-model回传（code数组）
	emit(
		"update:modelValue",
		[province?.[props.codeKey], city?.[props.codeKey], area?.[props.codeKey]].filter(
			Boolean
		)
	)
	// confirm事件回传完整对象
	emit("confirm", { province, city, area })
	popup.value && popup.value.close()
}

// 优化的索引查找函数，使用 Map 提高性能
function findIndexByCodes(tree, codes) {
	if (!Array.isArray(codes) || !codes.length || !tree.length) {
		return [0, 0, 0]
	}

	// 创建省份索引映射
	const provinceMap = new Map()
	tree.forEach((province, index) => {
		provinceMap.set(province[props.codeKey], index)
	})

	const provinceIndex = provinceMap.get(codes[0]) ?? 0
	const province = tree[provinceIndex]

	if (!codes[1] || !province?.children?.length) {
		return [provinceIndex, 0, 0]
	}

	// 创建城市索引映射
	const cityMap = new Map()
	province.children.forEach((city, index) => {
		cityMap.set(city[props.codeKey], index)
	})

	const cityIndex = cityMap.get(codes[1]) ?? 0
	const city = province.children[cityIndex]

	if (!codes[2] || !city?.children?.length) {
		return [provinceIndex, cityIndex, 0]
	}

	// 创建区域索引映射
	const areaMap = new Map()
	city.children.forEach((area, index) => {
		areaMap.set(area[props.codeKey], index)
	})

	const areaIndex = areaMap.get(codes[2]) ?? 0

	return [provinceIndex, cityIndex, areaIndex]
}

// 初始化region数据
watch(
	() => props.region,
	(val) => {
		regionData.value = Array.isArray(val) ? val : []
		// 数据更新后重新设置默认值
		if (props.modelValue?.length && regionData.value.length) {
			pickerValue.value = findIndexByCodes(regionData.value, props.modelValue)
		} else {
			pickerValue.value = [0, 0, 0]
		}
	},
	{ immediate: true }
)

// 外部v-model变化时同步
watch(
	() => props.modelValue,
	(val) => {
		if (val?.length && regionData.value.length) {
			pickerValue.value = findIndexByCodes(regionData.value, val)
		}
	}
)

// 暴露open方法
defineExpose({ open })
</script>

<style lang="scss" scoped>
.picker-container {
	background-color: #fff;
	border-radius: 20px 20px 0 0;
	overflow: hidden;
	padding-bottom: env(safe-area-inset-bottom);
	display: flex;
	flex-direction: column;
}
.picker-header {
	padding: 15px;
	display: flex;
	align-items: center;
	border-bottom: 1px solid #eee;
	background: #fff;
	.custom-easyinput {
		flex: 1;
		height: 36px;
		background: #f5f5f5 !important;
		border-radius: 18px !important;
		font-size: 14px !important;
		border: none !important;
		box-shadow: none !important;
		margin-right: 10px;
		display: flex;
		align-items: center;
		padding: 0 !important;
	}
	:deep(.uni-easyinput__content) {
		background: #f5f5f5 !important;
		border-radius: 18px !important;
		border: none !important;
		box-shadow: none !important;
		padding: 0 15px !important;
		min-height: 36px !important;
		height: 36px !important;
		display: flex;
		align-items: center;
	}
	:deep(.uni-easyinput__content-input) {
		background: transparent !important;
		border: none !important;
		box-shadow: none !important;
		font-size: 14px !important;
		height: 36px !important;
		line-height: 36px !important;
	}
	:deep(.uni-easyinput__icon) {
		color: #bfbfbf !important;
		right: 8px !important;
	}
	.confirm-btn {
		margin-left: 10px;
		font-size: 15px;
		font-weight: bold;
		flex-shrink: 0;
	}
}
.picker-body {
	flex: 1;
	.picker-view {
		width: 100%;
		height: 100%;
	}
	.picker-item {
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 14px;
	}
}
</style>
